home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 30
/
Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso
/
Aminet
/
gfx
/
show
/
FV21BETA-src.lha
/
FV21BETA-src
/
FVasm.s
< prev
next >
Wrap
Text File
|
1998-10-29
|
41KB
|
2,052 lines
; Abbrevations used:
;
; RGB = 3 bytes per pixel (R,G,B) 24bit.
; FTC = 1 byte per pixel. Fake True Color, the palette is set in such a way
; that it acts as a 8bit (or less) true color mode.
Opt l+,case
MC68000 EQU 0
XDef _RANDOM
XDef _RGBTOFTC
XDef _DECODEGIF
XDef _SCALERGB
XDef _SCALEGRAY
Incdir "INCLUDE:"
Include "exec/types.i"
Include "exec/nodes.i"
Include "FV.hi"
ToggleLed MACRO
Move.l d0,-(sp)
Moveq #-1,d0
Bset #1,$bfe001
.Loop\@ Move.l $0.l,$0.l
Dbra d0,.Loop\@
Bclr #1,$bfe001
Move.l (sp)+,d0
ENDM
; seed = ((seed + 7) * 257) % (2^31-1)
;$0ffff - $ffff = $0000 = $ffff + $0 = $ffff -> $0000
;$10000 - $ffff = $0001 = $0000 + $1 = $0001
;$1fffd - $ffff = $fffe = $fffd + $1 = $fffe
;$1fffe - $ffff*2 = $0000 = $fffe + $1 = $ffff -> $0000
;$1ffff - $ffff*2 = $0001 = $ffff + $1 = $0000 + X = $0001
;$20000 - $ffff*2 = $0002 = $0000 + $2 = $0002
;$2fffc - $ffff*2 = $fffe = $fffc + $2 = $fffe
;$2fffd - $ffff*3 = $0000 = $fffd + $2 = $ffff -> $0000
;$2fffe - $ffff*3 = $0001 = $fffe + $2 = $0000 + X = $0001
;$2ffff - $ffff*3 = $0002 = $ffff + $2 = $0001 + X = $0002
;$30000 - $ffff*3 = $0003 = $0000 + $3 = $0003
;$07fff - $7fff = $0000 = $7fff + $0 = $7fff - $7fff = $0000
;$08000 - $7fff = $0001 = $0000 + $1 = $0001
;$0fffd - $7fff = $7ffe = $7ffd + $1 = $7ffe
;$0fffe - $7fff*2 = $0000 = $7ffe + $1 = $7fff - $7fff = $0000
;$0ffff - $7fff*2 = $0001 = $7fff + $1 = $8000 - $7fff = $0001
;$10000 - $7fff*2 = $0002 = $0000 + $2 = $0002
;$17ffc - $7fff*2 = $7ffe = $
;$17ffd - $7fff*3 = $0000 = $7ffd + $2 = $7fff - $7fff = $0000
;$17ffe - $7fff*3 = $0001
;$17fff - $7fff*3 = $0002 = $7fff + $2 = $8001 - $7fff = $0002
;$18000 - $7fff*3 = $0003 = $0000 + $3 = $0003
;$808505 = $0505 + $101 = $0606
CNOP 0,4
_RANDOM ; IN: d0.l = Seed
;OUT: d0.l = New seed
Movem.l d1-d3,-(sp)
Moveq #0,d2
Move.l d0,d3
Moveq #0,d1 d1:d0 = seed
Addq.l #7,d0 d1:d0 = seed+7
Rol.l #8,d0
Move.b d0,d1
Clr.b d0 d1:d0 = (seed+7) * 256
Add.l d3,d0
Addx.w d2,d1 d1:d0 = (seed+7) * 257
Lsl.w #1,d1 Make room for a bit.
Lsl.l #1,d0 Shift highest bit into X.
Addx.w d2,d1 Highest bit of d0 shifted into lowest bit of d1
Lsr.l #1,d0 d0 is now automatically ANDed with $7fffffff
Add.l d1,d0
Move.l #$7fffffff,d1
Cmp.l d1,d0
Blo.s .Done
Sub.l d1,d0
.Done Movem.l (sp)+,d1-d3
Rts
; CNOP 0,4
;_RANDOM ; IN: d0.l = Seed
; ;OUT: d0.l = New seed
; Movem.l d1-d2,-(sp)
;
; Moveq #0,d1
; Move.w d0,d1
; Clr.w d0
; Swap d0
;
; Move.l d0,d2
; Lsl.l #8,d0
; Add.l d2,d0
;
; Move.l d1,d2
; Lsl.l #8,d1
; Add.l d2,d1
;
; Move.l d0,d2
; Swap d2
; And.l #$7fff0000,d2
; Add.l d2,d1
; Bvc.s .Skip
; Addq.l #1,d1
;
;.Skip Moveq #15,d2
; Lsr.l d2,d0
; Add.l d1,d0
; Bclr #31,d0
;
; Movem.l (sp)+,d1-d2
; Rts
CNOP 0,4
_SCALERGB ; IN: a0.l = Input (RGB buffer)
; IN: a1.l = Output (RGB buffer)
; IN: d0.w = Width in pixels
; IN: d1.w = Scalefactor (0-4095 for shrinking, 4096 for no scaling, 4097-32767 for enlarging)
Movem.l d0-d2/a0-a1,-(sp)
Move.w #-2048,d2
Subq.w #1,d0
Cmp.w #4096,d1
Bgt.s .Enlarging
.Loop Add.w d1,d2
Blt.s .GoLoop
Sub.w #4096,d2
Move.b (a0)+,(a1)+
Move.b (a0)+,(a1)+
Move.b (a0)+,(a1)+
Dbra d0,.Loop
Bra.s .Exit
.GoLoop Addq.l #3,a0
Dbra d0,.Loop
Bra.s .Exit
.Enlarging Add.w d1,d2
.Loop2 Move.b (a0),(a1)+
Move.b 1(a0),(a1)+
Move.b 2(a0),(a1)+
Sub.w #4096,d2
Bge.s .Loop2
Addq.l #3,a0
Dbra d0,.Enlarging
.Exit Movem.l (sp)+,d0-d2/a0-a1
Rts
CNOP 0,4
_SCALEGRAY ; IN: a0.l = Input (RGB buffer)
; IN: a1.l = Output (RGB buffer)
; IN: d0.w = Width in pixels
; IN: d1.w = Scalefactor (0-4095 for shrinking, 4096 for no scaling, 4097-32767 for enlarging)
Movem.l d0-d2/a0-a1,-(sp)
Move.w #-2048,d2
Subq.w #1,d0
Cmp.w #4096,d1
Bgt.s .Enlarging
.Loop Add.w d1,d2
Blt.s .GoLoop
Sub.w #4096,d2
Move.b (a0)+,(a1)+
Dbra d0,.Loop
Bra.s .Exit
.GoLoop Addq.l #1,a0
Dbra d0,.Loop
Bra.s .Exit
.Enlarging Add.w d1,d2
.Loop2 Move.b (a0),(a1)+
Sub.w #4096,d2
Bge.s .Loop2
Addq.l #1,a0
Dbra d0,.Enlarging
.Exit Movem.l (sp)+,d0-d2/a0-a1
Rts
CNOP 0,4
_RGBTOFTC ; IN: a0.l = Input (RGB buffer)
; IN: a1.l = Output (FTC buffer)
; IN: d0.w = Width in pixels
; IN: d1.w = Height in pixels
; IN: d2.w = Renderdepth
Movem.l a0-a2/d1-d2/d4-d7,-(sp)
Move.w d2,d4
Add.w d4,d4
Add.w d2,d4
Lea FTCtable-3(pc,d4.w),a2
Move.b (a2)+,d5
Move.b (a2)+,d6
Move.b (a2)+,d7
Subq.w #1,d1
.YLoop Move.w d0,d4
Subq.w #1,d4
.XLoop Moveq #0,d2
Move.b (a0)+,d2
Lsl.w d5,d2
Move.b (a0)+,d2
Lsl.w d6,d2
Move.b (a0)+,d2
Lsl.w d7,d2
Lsr.w #8,d2
Move.b d2,(a1)+
Dbra d4,.XLoop
Dbra d1,.YLoop
Movem.l (sp)+,a0-a2/d1-d2/d4-d7
Rts
FTCtable Dc.b 0,1,0
Dc.b 1,1,0
Dc.b 1,1,1
Dc.b 1,2,1
Dc.b 2,2,1
Dc.b 2,2,2
Dc.b 2,3,2
Dc.b 3,3,2
RsReset
Size Rs.w 1 0
Cursize Rs.w 1 2
Clearcode Rs.w 1 4
Endcode Rs.w 1 6
Newcodes Rs.w 1 8 not worth a register
Topslot Rs.w 1 10
Slot Rs.w 1 12
Navailbytes Rs.w 1 14
Nbitsleft Rs.w 1 16
Shiftreg Rs.w 1 18
Suffix Rs.l 1 20
Prefix Rs.l 1 24
Stack Rs.l 1 28
Sp Rs.l 1 32 stack current location
Oc Rs.w 1 36
Fc Rs.w 1 38
Row Rs.w 1 40
Interlaced Rs.b 1 42
CNOP 0,4
_DECODEGIF ; IN: a0.l = struct ScreenNode *
; IN: a1.l = UBYTE *buffer
; IN: d0.w = rows
;OUT: d0.l = Error code or zero if everything went okay.
Movem.l d1-d7/a0-a6,-(sp)
Move.l sn_BytesPerRow(a0),d7
Mulu d0,d7
Moveq #-lh_SIZEOF*8,d1
Move.w sn_Data+Row(a0),d2
Move.b sn_Data+Interlaced(a0),d3
Beq.s .LLoop
; 4 = NextStart = 2*4, step 8
; 3 = NextStart = 2*2, step 8
; 2 = NextStart = 2*1, step 4
; 1 = NextStart = 2*0.5, step 2
Cmp.b #2,d3
Blt.s .Type1
Beq.s .Type2
Cmp.b #3,d3
Beq.s .Type3
Moveq #8,d4
Moveq #8,d5
Bra.s .IntLoop
.Type3 Moveq #8,d4
Moveq #4,d5
Bra.s .IntLoop
.Type2 Moveq #4,d4
Moveq #2,d5
Bra.s .IntLoop
.Type1 Moveq #2,d4
Moveq #1,d5
.IntLoop Move.w d2,lh_Row(a1,d1.w)
Add.w d4,d2
Move.b d5,lh_Repeatrow(a1,d1.w)
.IntRetry Cmp.w sn_Height(a0),d2
Blt.s .IntCont
Subq.b #1,sn_Data+Interlaced(a0)
Lsr.w #1,d5 NextStart
Move.w d5,d2
Cmp.w #4,d5
Beq.s .IntSkip
Lsr.w #1,d4 Step
.IntSkip Bra.s .IntRetry
.IntCont Addq.w #lh_SIZEOF,d1
Bne.s .IntLoop
Bra.s .Continue
.LLoop Move.w d2,lh_Row(a1,d1.w)
Addq.w #1,d2
Move.b #1,lh_Repeatrow(a1,d1.w)
Addq.w #lh_SIZEOF,d1
Bne.s .LLoop
.Continue Move.w d2,sn_Data+Row(a0)
Move.w sn_Data+Nbitsleft(a0),d2
Move.w sn_Data+Navailbytes(a0),d3
Move.w sn_Data+Shiftreg(a0),d4
Move.w sn_Data+Cursize(a0),d5
Move.w sn_Data+Slot(a0),d6
Move.l sn_Data+Sp(a0),a2
Move.w sn_Data+Fc(a0),a3
Move.w sn_Data+Oc(a0),a4
Move.l sn_Data+Suffix(a0),a5
Move.l sn_Data+Prefix(a0),a6
;Register layout:
;d0.w = c
;d1.w = code, or scratch for getnextcode!
;d2.w = nbits_left
;d3.w = navail_bytes
;d4.w = b1 (shift-bit register) bits 8-15 must be clear always
;d5.w = curr_size
;d6.w = slot
;d7.l = bufcnt
;a0.l = ScreenNode *
;a1.l = UBYTE *buffer
;a2.l = sp (stack pointer)
;a3.w = fc
;a4.w = oc
;a5.l = suffix
;a6.l = prefix
.DoWhile Cmp.l sn_Data+Stack(a0),a2
Ble.s .Loop
Move.b -(a2),(a1)+
Subq.l #1,d7
Bne.s .DoWhile
; Save registers, loopinfo and stuff, then return
.SaveRegs Move.w d2,sn_Data+Nbitsleft(a0)
Move.w d3,sn_Data+Navailbytes(a0)
Move.w d4,sn_Data+Shiftreg(a0)
Move.w d5,sn_Data+Cursize(a0)
Move.w d6,sn_Data+Slot(a0)
Move.l a2,sn_Data+Sp(a0)
Move.w a3,sn_Data+Fc(a0)
Move.w a4,sn_Data+Oc(a0)
Moveq #0,d0
.Exit Movem.l (sp)+,d1-d7/a0-a6
Rts
.Loop Bsr GetNextCode
;OUT: d0 = the next code
Cmp.w sn_Data+Endcode(a0),d0
Beq.s .EndOfGif
Cmp.w sn_Data+Clearcode(a0),d0
Bne.s .NotClearCode
Move.w sn_Data+Size(a0),d5 cursize
Addq.w #1,d5
Moveq #1,d6
Lsl.w d5,d6
Move.w d6,sn_Data+Topslot(a0)
Move.w sn_Data+Newcodes(a0),d6 slot
.AnotherClearCode Bsr GetNextCode
;OUT: d0 = the next code
Cmp.w sn_Data+Clearcode(a0),d0
Beq.s .AnotherClearCode
Cmp.w sn_Data+Endcode(a0),d0
Bne.s .NotEnding
.EndOfGif Moveq #ERROR_END_OF_STREAM,d0
Bra.s .Exit
.NotEnding Cmp.w d0,d6 Code,Slot
Bgt.s .NotBeyondRange
Moveq #0,d0
.NotBeyondRange Move.w d0,a3
Move.w d0,a4
Move.b d0,(a1)+
Subq.l #1,d7
Bne.s .Loop
Bra .SaveRegs
.NotClearCode Move.w d0,d1
Cmp.w d1,d6 code,slot
Bgt.s .CodeIsInRange
;Beq.s .NotABadCode
;Encountered a bad code... what should we do with it?
;The example code simply increased a counter and ignored it.
.NotABadCode Move.w a4,d1
Exg a3,d0
Move.b d0,(a2)+
Exg a3,d0
.CodeIsInRange Cmp.w sn_Data+Newcodes(a0),d1
Blt.s .EndWhile
Move.b (a5,d1.w),(a2)+ suffix,stack
Move.w (a6,d1.w*2),d1 prefix,code
Bra.s .CodeIsInRange
.EndWhile Move.b d1,(a2)+
Cmp.w sn_Data+Topslot(a0),d6
Bge.s .Endif1
Move.b d1,(a5,d6.w)
Move.w d1,a3
Move.w a4,(a6,d6.w*2)
Addq.w #1,d6
Move.w d0,a4
.Endif1 Cmp.w sn_Data+Topslot(a0),d6
Blt.s .Endif2
Cmp.w #12,d5
Bge.s .Endif2
Lsl.w sn_Data+Topslot(a0)
Addq.w #1,d5
.Endif2 Bra .DoWhile
CNOP 0,4
GetNextCode ; IN: d1.l = SCRATCH
; IN: d2.w = nbits_left
; IN: d3.w = navail_bytes
; IN: d4.w = shift-bit register
; IN: d5.w = curr_size
; IN: a2.l = UBYTE *fileptr
;OUT: d0.w = the next code
; This routine gets next code which is d5 (curr_size) bits in size and
; returns this x bit code in the lower bits of d0. This routine can
; never fail since the buffer is pre-read, and so I/O errors are not
; of our concern.
Move.l a2,-(sp)
Move.l sn_FilePtr(a0),a2
Tst.w d2
Bne.s .NBitsLeftNotZero
Tst.w d3
Bgt.s .NAvailBytesPos
; No more bytes in current block, so read the next block-counter
Moveq #0,d3
Move.b (a2)+,d3
.NAvailBytesPos ; There were still bytes left in the current GIF block
Move.b (a2)+,d4
Moveq #8,d2
Subq.w #1,d3
.NBitsLeftNotZero Moveq #8,d1
Sub.w d2,d1
Move.w d4,d0
Lsr.w d1,d0
.While Cmp.w d5,d2
Bge.s .EndWhile
Tst.w d3
Bgt.s .NAvailBytesPos2
; No more bytes in current block, so read the next block-counter
Moveq #0,d3
Move.b (a2)+,d3
.NAvailBytesPos2 Move.b (a2)+,d4
Move.w d4,d1
Lsl.w d2,d1
Or.w d1,d0
Addq.w #8,d2
Subq.w #1,d3
Bra.s .While
.EndWhile Sub.w d5,d2
And.w CodeMask(pc,d5.w*2),d0
Move.l a2,sn_FilePtr(a0)
Move.l (sp)+,a2
Rts
CodeMask Dc.w 0,1,3,7,15,31,63,127,255,511,1023,2047,4095
END
/* DECODE.C - An LZW decoder for GIF
* Copyright (C) 1987, by Steven A. Bennett
*
* Permission is given by the author to freely redistribute and include
* this code in any program as long as this credit is given where due.
*
* In accordance with the above, I want to credit Steve Wilhite who wrote
* the code which this is heavily inspired by...
*
* GIF and 'Graphics Interchange Format' are trademarks (tm) of
* Compuserve, Incorporated, an H&R Block Company.
*
* Release Notes: This file contains a decoder routine for GIF images
* which is similar, structurally, to the original routine by Steve Wilhite.
* It is, however, somewhat noticably faster in most cases.
*
*/
#include "std.h"
#include "errs.h"
IMPORT TEXT *malloc(); /* Standard C library allocation */
/* IMPORT INT get_byte()
*
* - This external (machine specific) function is expected to return
* either the next byte from the GIF file, or a negative number, as
* defined in ERRS.H.
*/
IMPORT INT get_byte();
/* IMPORT INT out_line(pixels, linelen)
* UBYTE pixels[];
* INT linelen;
*
* - This function takes a full line of pixels (one byte per pixel) and
* displays them (or does whatever your program wants with them...). It
* should return zero, or negative if an error or some other event occurs
* which would require aborting the decode process... Note that the length
* passed will almost always be equal to the line length passed to the
* decoder function, with the sole exception occurring when an ending code
* occurs in an odd place in the GIF file... In any case, linelen will be
* equal to the number of pixels passed...
*/
IMPORT INT out_line();
/* IMPORT INT bad_code_count;
*
* This value is the only other global required by the using program, and
* is incremented each time an out of range code is read by the decoder.
* When this value is non-zero after a decode, your GIF file is probably
* corrupt in some way...
*/
IMPORT INT bad_code_count;
#define NULL 0L
#define MAX_CODES 4095
/* Static variables */
LOCAL WORD curr_size; /* The current code size */
LOCAL WORD clear; /* Value for a clear code */
LOCAL WORD ending; /* Value for a ending code */
LOCAL WORD newcodes; /* First available code */
LOCAL WORD top_slot; /* Highest code for current size */
LOCAL WORD slot; /* Last read code */
/* The following static variables are used
* for seperating out codes
*/
LOCAL WORD navail_bytes = 0; /* # bytes left in block */
LOCAL WORD nbits_left = 0; /* # bits left in current byte */
LOCAL UTINY b1; /* Current byte */
LOCAL UTINY byte_buff[257]; /* Current block */
LOCAL UTINY *pbytes; /* Pointer to next byte in block */
LOCAL LONG code_mask[13] = {
0,
0x0001, 0x0003,
0x0007, 0x000F,
0x001F, 0x003F,
0x007F, 0x00FF,
0x01FF, 0x03FF,
0x07FF, 0x0FFF
};
/* This function initializes the decoder for reading a new image.
*/
LOCAL WORD init_exp(WORD size) {
curr_size = size + 1;
top_slot = 1 << curr_size;
clear = 1 << size;
ending = clear + 1;
slot = newcodes = ending + 1;
navail_bytes = nbits_left = 0;
return(0);
}
/* get_next_code()
* - gets the next code from the GIF file. Returns the code, or else
* a negative number in case of file errors...
*/
LOCAL WORD get_next_code() {
WORD i, x;
ULONG ret;
if (nbits_left == 0) {
if (navail_bytes <= 0) {
/* Out of bytes in current block, so read next block
*/
pbytes = byte_buff;
if ((navail_bytes = get_byte()) < 0)
return(navail_bytes);
else if (navail_bytes) {
for (i = 0; i < navail_bytes; ++i) {
if ((x = get_byte()) < 0)
return(x);
byte_buff[i] = x;
}
}
}
b1 = *pbytes++;
nbits_left = 8;
--navail_bytes;
}
ret = b1 >> (8 - nbits_left);
while (curr_size > nbits_left) {
if (navail_bytes <= 0) {
/* Out of bytes in current block, so read next block
*/
pbytes = byte_buff;
if ((navail_bytes = get_byte()) < 0)
return(navail_bytes);
else if (navail_bytes) {
for (i = 0; i < navail_bytes; ++i) {
if ((x = get_byte()) < 0)
return(x);
byte_buff[i] = x;
}
}
}
b1 = *pbytes++;
ret |= b1 << nbits_left;
nbits_left += 8;
--navail_bytes;
}
nbits_left -= curr_size;
ret &= code_mask[curr_size];
return((WORD)(ret));
}
/* The reason we have these seperated like this instead of using
* a structure like the original Wilhite code did, is because this
* stuff generally produces significantly faster code when compiled...
* This code is full of similar speedups... (For a good book on writing
* C for speed or for space optomisation, see Efficient C by Tom Plum,
* published by Plum-Hall Associates...)
*/
LOCAL UTINY stack[MAX_CODES + 1]; /* Stack for storing pixels */
LOCAL UTINY suffix[MAX_CODES + 1]; /* Suffix table */
LOCAL UWORD prefix[MAX_CODES + 1]; /* Prefix linked list */
/* WORD decoder(linewidth)
* WORD linewidth; * Pixels per line of image *
*
* - This function decodes an LZW image, according to the method used
* in the GIF spec. Every *linewidth* "characters" (ie. pixels) decoded
* will generate a call to out_line(), which is a user specific function
* to display a line of pixels. The function gets it's codes from
* get_next_code() which is responsible for reading blocks of data and
* seperating them into the proper size codes. Finally, get_byte() is
* the global routine to read the next byte from the GIF file.
*
* It is generally a good idea to have linewidth correspond to the actual
* width of a line (as specified in the Image header) to make your own
* code a bit simpler, but it isn't absolutely necessary.
*
* Returns: 0 if successful, else negative. (See ERRS.H)
*
*/
WORD decoder(WORD linewidth) {
FAST UTINY *sp, *bufptr;
UTINY *buf;
FAST WORD code, fc, oc, bufcnt;
WORD c, size, ret;
/* Initialize for decoding a new image...
*/
if ((size = get_byte()) < 0)
return(size);
if (size < 2 || 9 < size)
return(BAD_CODE_SIZE);
init_exp(size);
/* Initialize in case they forgot to put in a clear code.
* (This shouldn't happen, but we'll try and decode it anyway...)
*/
oc = fc = 0;
/* Allocate space for the decode buffer
*/
if ((buf = (UTINY *)malloc(linewidth + 1)) == NULL)
return(OUT_OF_MEMORY);
/* Set up the stack pointer and decode buffer pointer
*/
sp = stack;
bufptr = buf;
bufcnt = linewidth;
/* This is the main loop. For each code we get we pass through the
* linked list of prefix codes, pushing the corresponding "character" for
* each code onto the stack. When the list reaches a single "character"
* we push that on the stack too, and then start unstacking each
* character for output in the correct order. Special handling is
* included for the clear code, and the whole thing ends when we get
* an ending code.
*/
while ((c = get_next_code()) != ending) {
/* If we had a file error, return without completing the decode
*/
if (c < 0)
{
free(buf);
return(0);
}
/* If the code is a clear code, reinitialize all necessary items.
*/
if (c == clear) {
curr_size = size + 1;
slot = newcodes;
top_slot = 1 << curr_size;
/* Continue reading codes until we get a non-clear code
* (Another unlikely, but possible case...)
*/
while ((c = get_next_code()) == clear)
;
/* If we get an ending code immediately after a clear code
* (Yet another unlikely case), then break out of the loop.
*/
if (c == ending)
break;
/* Finally, if the code is beyond the range of already set codes,
* (This one had better NOT happen... I have no idea what will
* result from this, but I doubt it will look good...) then set it
* to color zero.
*/
if (c >= slot)
c = 0;
oc = fc = c;
/* And let us not forget to put the char into the buffer... And
* if, on the off chance, we were exactly one pixel from the end
* of the line, we have to send the buffer to the out_line()
* routine...
*/
*bufptr++ = c;
if (--bufcnt == 0) {
if ((ret = out_line(buf, linewidth)) < 0) {
free(buf);
return(ret);
}
bufptr = buf;
bufcnt = linewidth;
}
}
else {
/* In this case, it's not a clear code or an ending code, so
* it must be a code code... So we can now decode the code into
* a stack of character codes. (Clear as mud, right?)
*/
code = c;
/* Here we go again with one of those off chances... If, on the
* off chance, the code we got is beyond the range of those already
* set up (Another thing which had better NOT happen...) we trick
* the decoder into thinking it actually got the last code read.
* (Hmmn... I'm not sure why this works... But it does...)
*/
if (code >= slot) {
if (code > slot)
++bad_code_count;
code = oc;
*sp++ = fc;
}
/* Here we scan back along the linked list of prefixes, pushing
* helpless characters (ie. suffixes) onto the stack as we do so.
*/
while (code >= newcodes) {
*sp++ = suffix[code]; // bytes
code = prefix[code]; // words
}
/* Push the last character on the stack, and set up the new
* prefix and suffix, and if the required slot number is greater
* than that allowed by the current bit size, increase the bit
* size. (NOTE - If we are all full, we *don't* save the new
* suffix and prefix... I'm not certain if this is correct...
* it might be more proper to overwrite the last code...
*/
*sp++ = code;
if (slot < top_slot) {
suffix[slot] = fc = code;
prefix[slot++] = oc;
oc = c;
}
if (slot >= top_slot) {
if (curr_size < 12) {
top_slot <<= 1;
++curr_size;
}
}
/* Now that we've pushed the decoded string (in reverse order)
* onto the stack, lets pop it off and put it into our decode
* buffer... And when the decode buffer is full, write another
* line...
*/
while (sp > stack) {
*bufptr++ = *(--sp);
if (--bufcnt == 0) {
if ((ret = out_line(buf, linewidth)) < 0) {
free(buf);
return(ret);
}
bufptr = buf;
bufcnt = linewidth;
}
}
}
}
ret = 0;
if (bufcnt != linewidth)
ret = out_line(buf, (linewidth - bufcnt));
free(buf);
return(ret);
}
END
ERROR_WHILE_DECODING = 25
MC68000 EQU 0
Opt l+
XDef _DECODEJPEG
Incdir "INCLUDE:"
Include "exec/nodes.i"
Include "exec/types.i"
Include "WORK:GifRtnFV.s"
STRUCTURE ScreenNode,0
STRUCT sn_node,LN_SIZE
STRUCT sn_data,16 ; private to the XXX functions
UWORD sn_width ; these describe the picture on disk
UWORD sn_height
UWORD sn_depth ; 2^depth is not necessarily the number of colors (HAM)
UWORD sn_colors ; not initid if truecolor = TRUE
UWORD sn_aspectx
UWORD sn_aspecty
; following UBYTE's are TRUE or FALSE
UBYTE sn_truecolor ; No palette-info depth 1-8 = gray depth 15,16,24 = color
UBYTE sn_ham ; depth 6 = HAM6 depth 8 = HAM8
UBYTE sn_ehb
UBYTE sn_planar
; now follows space for a 256-color palette (4 bytes/entry)
STRUCT sn_palette,1024
; following UBYTE's are TRUE or FALSE and are set by the BestModeID function
; to help the rendering routines
UBYTE sn_rerender
UBYTE sn_gray
UBYTE sn_deep ; not set means HAM6/GRAY4, set means HAM8/GRAY8
UBYTE sn_halvewidth
UBYTE sn_direct ; direct HAM or EHB, if TRUE then rerender must be FALSE
UBYTE sn_pad
WORD sn_renderaspect
ULONG sn_displayid
UWORD sn_nominalw
UWORD sn_nominalh
; following fields are not to be modified by the initXXX or exitXXX routines
ULONG sn_lock ; lock on the dir this file is located in
APTR sn_screen
APTR sn_window
ULONG sn_buffer
UWORD sn_renderw
UWORD sn_renderh
UWORD sn_renderd
UWORD sn_pad2
ULONG sn_buffersmemory
ULONG sn_linebuffer
ULONG sn_rgbbuffer
ULONG sn_bytebuffer
ULONG sn_floydbuf1
ULONG sn_floydbuf2
UWORD sn_outputline
CNOP 0,4
_DECODEJPEG ; IN: a0.l = struct ScreenNode *
;OUT: d0.l = Error code, zero if okay
Movem.l d1-d7/a0-a5,-(sp)
Move.l a0,a5
.YLoop ;SingleLine
Moveq #0,d2
Move.w sn_width(a5),d2
; Cmp.w #1,d7
; Beq.s .Gray
Add.w d2,d2
Add.w sn_width(a5),d2
;.Gray
Move.l d2,-(sp) Bufsize
Move.l sn_rgbbuffer(a5),-(sp) Buffer
Move.l #$73202,-(sp) CDM_PROCESS
Move.l sn_data(a5),-(sp) Object
Bsr DoMethod
Lea 16(sp),sp
Cmp.l d0,d2
Bne.s .Error
Bsr ProcessLine
;Bsr CheckMouse
;Bne.s .UserExited
Dbra d6,.YLoop
Moveq #0,d0
.Exit Movem.l (sp)+,d1-d7/a0-a5
Rts
.Error Moveq #ERROR_WHILE_DECODING,d0
Bra.s .Exit
CNOP 0,4
DoMethod Move.l A2,-(SP)
Movea.l $8(SP),A2
Move.l A2,D0
Beq.s LabA9A
Lea $C(SP),A1
Movea.l -$4(A2),A0
Bra.s LabA90
Move.l A2,-(SP)
Movem.l $8(SP),A0/A2
Move.l A2,D0
Beq.s LabA9A
Move.l A0,D0
Beq.s LabA9A
Lea $10(SP),A1
Movea.l $18(A0),A0
Bra.s LabA90
Move.l A2,-(SP)
Movem.l $8(SP),A0/A2
Move.l A2,D0
Beq.s LabA9A
Move.l A0,D0
Beq.s LabA9A
Lea $10(SP),A1
Bra.s LabA90
Move.l A2,-(SP)
Movem.l $8(SP),A0/A2
Move.l A2,D0
Beq.s LabA9A
Move.l A0,D0
Beq.s LabA9A
Movea.l $10(SP),A1
LabA90 Pea LabA9C
Move.l $8(A0),-(SP)
Rts
LabA9A Moveq #$0,D0
LabA9C Movea.l (SP)+,A2
Rts
CNOP 0,4
ProcessLine ; IN: a5.l = struct ScreenNode *
Movem.l d0-d7/a0-a6,-(sp)
Tst.b sn_halvewidth(a5)
Beq.s .HAM.NoHalve
Move.l sn_rgbbuffer(a5),a0
Move.w sn_width(a5),d0
Bsr HalveRGB
.HAM.NoHalve Move.l sn_rgbbuffer(a5),a0
Move.l sn_bytebuffer(a5),a1
Lea HamPalette(pc),a2
Lea CacheMem(pc),a3
Move.w sn_width(a5),d0
; IN: a0.l = Ptr to RGB line (3 words/color)
; IN: a1.l = Ptr to HAM output buffer
; IN: a2.l = Ptr to HAM-palette (4 words/color)
; IN: a3.l = Ptr to 32768 bytes of cache memory
; IN: d0.w = Length of RGB in pixels
Bsr RGBtoHAM
Move.l sn_bytebuffer(a5),a0
Move.w sn_outputline(a5),d1
Addq.w #1,sn_outputline(a5)
Bsr ChunkyToPlanar destroys -all- registers
Movem.l (sp)+,d0-d7/a0-a6
Rts
HamPalette Dc.w 0,$00,$00,$00
Dc.w 0,$11,$11,$11
Dc.w 0,$22,$22,$22
Dc.w 0,$33,$33,$33
Dc.w 0,$44,$44,$44
Dc.w 0,$55,$55,$55
Dc.w 0,$66,$66,$66
Dc.w 0,$77,$77,$77
Dc.w 0,$88,$88,$88
Dc.w 0,$99,$99,$99
Dc.w 0,$aa,$aa,$aa
Dc.w 0,$bb,$bb,$bb
Dc.w 0,$cc,$cc,$cc
Dc.w 0,$dd,$dd,$dd
Dc.w 0,$ee,$ee,$ee
Dc.w 0,$ff,$ff,$ff
CacheMem Ds.b 4096
END
output the line
Tst.l Cat(a5)
Beq.s .Cont
Bra OutputLineRtnCat
.Cont Movem.l d0-d7/a0-a6,-(sp)
Tst.l Scale(a5)
Beq.s .NoScale
Move.w ScaleLevel(a5),d0
Add.w d0,VerScale(a5)
Blt .Exit
Sub.w #64,VerScale(a5)
.NoScale Tst.b sn_planar(a4) Planar or Chunky?
Beq .Chunky
Move.w sn_width(a4),d0
Move.l sn_linebuffer(a4),a2
Cmp.w #24,sn_depth(a4)
Bne.s .Normal
Moveq #1,d3
Move.l sn_rgbbuffer(a4),a0
Bsr PlanarToChunky
Move.w sn_width(a4),d0
Add.w #15,d0
And.w #-16,d0
Add.w d0,a2
Move.w sn_width(a4),d0
Addq.l #1,a0
Bsr PlanarToChunky
Move.w sn_width(a4),d0
Add.w #15,d0
And.w #-16,d0
Add.w d0,a2
Move.w sn_width(a4),d0
Addq.l #1,a0
Bsr PlanarToChunky
Bra.s .Chunky
.Normal Move.l sn_bytebuffer(a4),a0
Moveq #0,d3
Bsr PlanarToChunky
Tst.b sn_ham(a4)
Beq.s .Chunky
Tst.b sn_rerender(a4)
Beq.s .Chunky
Tst.b sn_gray(a4)
Bne.s .Chunky
Cmp.w #8,sn_depth(a4)
Bne.s .Chunky
Move.w sn_width(a4),d0
Move.l a0,a2
Move.l sn_rgbbuffer(a4),a0
Lea sn_palette(a4),a1
Bsr HAM8ToRGB
.Chunky Tst.b sn_rerender(a4)
Beq.s .Direct
Tst.b sn_gray(a4)
Bne.s .Gray
Bra .HAM
.Direct Move.l sn_bytebuffer(a4),a0
Tst.b sn_truecolor(a4)
Beq.s .NotGray
Cmp.w #8,sn_depth(a4)
Bgt.s .NotGray
Move.l sn_rgbbuffer(a4),a0
.NotGray
Tst.l Scale(a5)
Beq.s .Direct.NoScale
Move.w sn_RenderW(a4),d1
Bsr PaletteScalerSimple preserves A0
.Direct.NoScale Move.l a0,a1
Bra .Render8bit
.Gray Btst #0,DataInput(a5) 24 bit or 8 bit?
Beq.s .Gray.8bit
Move.l RGBBuffer(a5),a0
Move.w sn_W(a4),d0
Bsr RGBtoGray
Bra.s .Gray.Render
.Gray.8bit Btst #1,DataInput(a5)
Bne.s .Gray.Render
Move.l RGBBuffer(a5),a0
Lea sn_Palette(a4),a1
Move.l ByteBuffer(a5),a2
Move.w sn_W(a4),d0
Bsr PaletteToGray
.Gray.Render Tst.l Scale(a5)
Beq.s .Gray.NoScale
Move.l RGBBuffer(a5),a0
Move.w sn_RenderW(a4),d1
Bsr GrayScalerSimple
.Gray.NoScale Move.l RGBBuffer(a5),a0
Move.l ByteBuffer(a5),a1
Move.w sn_W(a4),d0
Moveq #8,d1
Sub.w sn_RenderDepth(a4),d1
Tst.l Dither(a5)
Bne.s .Gray.Dither
Bsr RGBtoBW d0-d1 destroyed
Bra .Render8bit
.Gray.Dither Bsr RGBtoBWdither d0-d2 destroyed
Bra .Render8bit
.HAM Btst #0,DataInput(a5) 24 bit or 8 bit?
Bne.s .HAM.24bit
Move.l RGBBuffer(a5),a0
Lea sn_Palette(a4),a1
Move.l ByteBuffer(a5),a2
Move.w sn_W(a4),d0
Bsr PaletteToRGB d0-d4 destroyed
Bra.s .HAM.NoHalve
.HAM.24bit Tst.b HalveWidth(a5)
Beq.s .HAM.NoHalve
Move.l RGBBuffer(a5),a0
Move.w sn_W(a4),d0
Bsr HalveRGB
.HAM.NoHalve Tst.l MakeComment(a5)
Beq.s .HAM.NoHistogram
Tst.b HistogramAvailable(a5)
Bne.s .HAM.NoHistogram
Move.l RGBBuffer(a5),a2
Move.l a5,a1
Add.l #Histogram,a1
Move.w sn_W(a4),d0
Tst.b HalveWidth(a5)
Beq.s .HAM.NoHalve2
Addq.w #1,d0
Lsr.w #1,d0
.HAM.NoHalve2 Subq.w #1,d0
.HAM.Loop Move.b (a2)+,d3
Lsl.w #4,d3
Move.b (a2)+,d3
Lsl.w #4,d3
Move.b (a2)+,d3
Lsr.w #4,d3
IFNE MC68000
Add.w d3,d3
Move.w (a1,d3.w),d2
ELSE
Move.w (a1,d3.w*2),d2
ENDC
Cmp.w #65530,d2
Bhi.s .HAM.NoInc
Addq.w #1,d2
IFNE MC68000
Move.w d2,(a1,d3.w)
ELSE
Move.w d2,(a1,d3.w*2)
ENDC
IFNE MC68000
Add.w d3,d3
Addq.w #1,(a1,d3.w)
ELSE
Addq.w #1,(a1,d3.w*2)
ENDC
Bcc.s .HAM.NoInc
IFNE MC68000
Move.w #65530,(a1,d3.w)
ELSE
Move.w #65530,(a1,d3.w*2)
ENDC
.HAM.NoInc Dbra d0,.HAM.Loop
.HAM.NoHistogram Tst.l Scale(a5)
Beq.s .HAM.NoScale
Move.l RGBBuffer(a5),a0
Move.w sn_RenderW(a4),d1
Bsr RGBScalerSimple
.HAM.NoScale Move.w sn_RenderW(a4),d0
Move.l RGBBuffer(a5),a0
Move.l ByteBuffer(a5),a1
Lea sn_RenderPalette(a4),a2
Move.l a5,a3
Add.l #Cache,a3
Tst.l Dither(a5)
Bne.s .HAM.Dither
Cmp.b #3,Render+1(a5)
Beq.s .HAM8.NoDither
Bsr RGBtoHAM d0-d7 destroyed
Bra.s .Render8bit
.HAM8.NoDither Bsr RGBtoHAM8 d0-d7 destroyed
Bra.s .Render8bit
.HAM.Dither Cmp.b #3,Render+1(a5)
Beq.s .HAM8.Dither
Bsr RGBtoHAMdither d0-d7 destroyed
Bra.s .Render8bit
.HAM8.Dither Bsr RGBtoHAM8dither d0-d7 destroyed
Bra .Render8bit
.Render8bit ; IN: a1.l = Ptr to 8-bit buffer
Move.l a1,a0
.NotByteBuffer Move.l sn_Screen(a4),d0
Bne.s .RenderToScreen
Move.l sn_BufferCurrent(a4),a1
Move.w sn_RoundW(a4),d0
Lsr.w #4,d0
Subq.w #1,d0
.CopyToBuffer Move.l (a0)+,(a1)+
Move.l (a0)+,(a1)+
Move.l (a0)+,(a1)+
Move.l (a0)+,(a1)+
Dbra d0,.CopyToBuffer
Move.l a1,sn_BufferCurrent(a4)
Bra.s .Exit
.RenderToScreen Move.l d0,a1
Bsr RenderLineToScreen
.Exit Movem.l (sp)+,d0-d7/a0-a6
Rts
RenderLineToScreen ; IN: a0.l = ByteBuffer (source)
; IN: a1.l = Ptr to screen
; IN: a4.l = ScreenNode
Movem.l d0-d7/a0-a6,-(sp)
Move.w sn_OutputLine(a4),d1
Move.w sn_PicType(a4),d0 !!!!
Cmp.w #"IF",d0
Bne.s .CheckRest
Tst.b Render+1(a5)
Bne.s .NotInterlaced
Addq.w #1,sn_OutputLine(a4)
Move.w sn_RenderW(a4),d2
Bsr PlanarToPlanar
Bra.s .Exit
Beq.s .NotInterlaced
.CheckRest Cmp.w #"JP",d0
Beq.s .NotInterlaced
Cmp.w #"BM",d0
Beq.s .Backwards
Cmp.w #"PC",d0
Beq.s .NotInterlaced
Must be GIF
Btst #6,sn_SpecialInfo+1(a4)
Beq.s .NotInterlaced
Move.w d1,d2
Sub.w FontH(a5),d2
Move.b sn_SpecialInfo(a4),d3
Beq.s .Step8
Subq.b #2,d3
Beq.s .Step4
Blt.s .Step8b
.Step2 Addq.w #2,d2
Bra.s .Done
.Step4 Addq.w #4,d2
Cmp.w sn_H(a4),d2
Blt.s .Done
Addq.b #1,sn_SpecialInfo(a4)
Moveq #1,d2
Bra.s .Done
.Step8b Addq.w #8,d2
Cmp.w sn_H(a4),d2
Blt.s .Done
Addq.b #1,sn_SpecialInfo(a4)
Moveq #2,d2
Bra.s .Done
.Step8 Addq.w #8,d2
Cmp.w sn_H(a4),d2
Blt.s .Done
Addq.b #1,sn_SpecialInfo(a4)
Moveq #4,d2
.Done Add.w FontH(a5),d2
Move.w d2,sn_OutputLine(a4)
Bra.s .DoC2P
.Backwards Subq.w #1,sn_OutputLine(a4)
Bra.s .DoC2P
.NotInterlaced Addq.w #1,sn_OutputLine(a4)
.DoC2P Move.w sn_RenderW(a4),d2
Bsr ChunkyToPlanar
.Exit Movem.l (sp)+,d0-d7/a0-a6
Rts
PlanarToChunky ; IN: a0.l = Ptr to output buffer
; IN: a2.l = Ptr to planar data
; IN: d0.w = Width of line in pixels
; IN: d3.w = 0: Palette data 1: 24-bit data
;COM: d0-d2/d4-d7 destroyed
Movem.l a0-a5,-(sp)
Add.w #15,d0
Lsr.w #4,d0
Add.w d0,d0
Move.w d0,a1 1x
Lea (a1,d0.w),a5 2x
; a2 points to BP 0
Lea (a2,a5.l),a3 a3 points to BP 2
Lea (a3,a5.l),a4 a4 points to BP 4
Lea (a4,a5.l),a5 a5 points to BP 6
Move.l #$f0f0f0f0,d6
Move.l #$cccc3333,d7
Subq.w #1,d0
.Loop Move.b (a4,a1.l),d4 BP 5
Swap d4
Move.b (a5,a1.l),d4 BP 7
Lsl.l #8,d4
Move.b (a5)+,d4 BP 6
Swap d4
Move.b (a4)+,d4 BP 4
Move.b (a2,a1.l),d5 BP 1
Swap d5
Move.b (a3,a1.l),d5 BP 3
Lsl.l #8,d5
Move.b (a3)+,d5 BP 2
Swap d5
Move.b (a2)+,d5 BP 0
Move.l d4,d1
Move.l d5,d2
And.l d6,d4
And.l d6,d2
Eor.l d4,d1
Eor.l d2,d5
Lsr.l #4,d2
Lsl.l #4,d1
Or.l d2,d4
Or.l d1,d5
Move.l d4,d1
And.l d7,d4
Eor.l d4,d1
Lsr.w #2,d1
Swap d1
Lsl.w #2,d1
Or.l d1,d4
Move.l d5,d1
And.l d7,d5
Eor.l d5,d1
Lsr.w #2,d1
Swap d1
Lsl.w #2,d1
Or.l d1,d5
Move.l d4,d1
And.l #$aa55aa55,d4
Eor.l d4,d1
Lsr.b #1,d1
Rol.w #8,d1
Add.b d1,d1
Swap d1
Lsr.b #1,d1
Rol.w #8,d1
Add.b d1,d1
Swap d1
Or.l d1,d4
Move.l d5,d1
And.l #$aa55aa55,d5
Eor.l d5,d1
Lsr.b #1,d1
Rol.w #8,d1
Add.b d1,d1
Swap d1
Lsr.b #1,d1
Rol.w #8,d1
Add.b d1,d1
Swap d1
Or.l d1,d5
Tst.b d3
Bne.s .24bit
Move.l d4,(a0)+
Move.l d5,(a0)+
Dbra d0,.Loop
Bra.s .Exit
.24bit Move.b d4,9(a0)
Lsr.w #8,d4
Move.b d4,6(a0)
Swap d4
Move.b d4,3(a0)
Lsr.w #8,d4
Move.b d4,(a0)
Move.b d5,21(a0)
Lsr.w #8,d5
Move.b d5,18(a0)
Swap d5
Move.b d5,15(a0)
Lsr.w #8,d5
Move.b d5,12(a0)
Lea 24(a0),a0
Dbra d0,.Loop
.Exit Movem.l (sp)+,a0-a5
Rts
CNOP 0,4
HAM8ToRGB ; IN: a0.l = Ptr to RGB output buffer
; IN: a1.l = Ptr to palette (4 bytes/entry)
; IN: a2.l = Ptr to Palette-line (1 byte/pixel)
; IN: d0.w = Length of Palette-line in pixels
Movem.l a0/a2,-(sp)
Moveq #0,d5
Move.b 1(a1),d5
Moveq #0,d6
Move.b 2(a1),d6
Moveq #0,d7
Move.b 3(a1),d7
Subq.w #1,d0
.Loop Moveq #0,d1
Move.b (a2)+,d1
Move.w d1,d2
And.w #$3f,d1
Eor.w d1,d2
Sub.w #64,d2
Beq.s .Blue
Blt.s .Color
Tst.b d2
Blt.s .Green
.Red Lsl.b #2,d1
And.w #3,d5
Or.w d1,d5
Bra.s .DoLoop
.Blue Lsl.b #2,d1
And.w #3,d7
Or.w d1,d7
Bra.s .DoLoop
.Green Lsl.b #2,d1
And.w #3,d6
Or.w d1,d6
Bra.s .DoLoop
.Color
IFNE MC68000
Lsl.w #2,d1
Move.b 1(a1,d1.w),d5
Move.b 2(a1,d1.w),d6
Move.b 3(a1,d1.w),d7
ELSE
Move.b 1(a1,d1.w*4),d5
Move.b 2(a1,d1.w*4),d6
Move.b 3(a1,d1.w*4),d7
ENDC
.DoLoop Move.b d5,(a0)+
Move.b d6,(a0)+
Move.b d7,(a0)+
Dbra d0,.Loop
Movem.l (sp)+,a0/a2
Rts
CNOP 0,4
RGBtoGray ; IN: a0.l = Ptr to RGB buffer (in- and output)
; IN: d0.w = Length of Palette-line in pixels
Movem.l a0-a1,-(sp)
Move.l a0,a1
.Loop Moveq #0,d1
Move.b (a1)+,d1 Red component
Move.w d1,d2
Lsl.w #3,d1
Add.w d1,d2
Moveq #0,d1
Move.b (a1)+,d1 Green component
Add.w d1,d2
Add.w d1,d2
Add.w d1,d2
Lsl.w #4,d1
Add.w d1,d2
Moveq #0,d1
Move.b (a1)+,d1 Blue component
Lsl.w #2,d1
Add.w d1,d2
Add.w #16,d2
Lsr.w #5,d2
Move.b d2,(a0)+
Dbra d0,.Loop
;R:G:B = 9:19:4 (32) => 281:594:125
;R:G:B = 290:597:113
Movem.l (sp)+,a0-a1
Rts
CNOP 0,4
PaletteToRGB ; IN: a0.l = Ptr to RGB output buffer
; IN: a1.l = Ptr to palette (4 bytes/entry)
; IN: a2.l = Ptr to Palette-line (1 byte/pixel)
; IN: d0.w = Length of Palette-line in pixels
;COM: d0-d4 destroyed
Movem.l a0/a2,-(sp)
Moveq #0,d1
Tst.b HalveWidth(a5)
Beq.s .Loop2
Move.l #$fefefe,d5
Addq.w #1,d0
Lsr.w #1,d0
Subq.w #1,d0
.LoopDownScaleBy2 Move.b (a2)+,d1 Color Number
IFNE MC68000
Lsl.w #2,d1
Move.l (a1,d1.w),d3
Moveq #0,d1
ELSE
Move.l (a1,d1.w*4),d3
ENDC
And.l d5,d3
Move.b (a2)+,d1
IFNE MC68000
Lsl.w #2,d1
Move.l (a1,d1.w),d4
Moveq #0,d1
ELSE
Move.l (a1,d1.w*4),d4
ENDC
And.l d5,d4
Add.l d4,d3
Lsr.l #1,d3
IFNE MC68000
Move.b d3,2(a0)
Lsr.w #8,d3
Move.b d3,1(a0)
Swap d3
Move.b d3,(a0)
ELSE
Move.w d3,1(a0)
Swap d3
Move.b d3,(a0)
ENDC
Addq.l #3,a0
Dbra d0,.LoopDownScaleBy2
Bra.s .GoOn
.Loop2 Subq.w #1,d0
.Loop Move.b (a2)+,d1
IFNE MC68000
Lsl.w #2,d1
Move.b 1(a1,d1.w),(a0)+
Move.b 2(a1,d1.w),(a0)+
Move.b 3(a1,d1.w),(a0)+
Moveq #0,d1
ELSE
Move.b 1(a1,d1.w*4),(a0)+
Move.w 2(a1,d1.w*4),(a0)+
ENDC
Dbra d0,.Loop
.GoOn Clr.b (a0)+
Clr.b (a0)+
Clr.b (a0)+
Movem.l (sp)+,a0/a2
Rts
CNOP 0,4
PaletteToGray ; IN: a0.l = Ptr to Gray output buffer
; IN: a1.l = Ptr to palette (4 bytes/entry)
; IN: a2.l = Ptr to Palette-line (1 byte/pixel)
; IN: d0.w = Length of Palette-line in pixels
;COM: d0-d4 destroyed
Movem.l a0/a2,-(sp)
Moveq #0,d1
Subq.w #1,d0
.Loop Move.b (a2)+,d1
Move.b (a1,d1.w),(a0)+
Dbra d0,.Loop
.GoOn Clr.b (a0)+
Movem.l (sp)+,a0/a2
Rts
CNOP 0,4
HalveRGB ; IN: a0.l = RGB Buffer (3 bytes/pixel)
; IN: d0.w = Number of pixels in RGB Buffer
Movem.l a0-a1,-(sp)
Move.l a0,a1
Move.l #$fefefe,d7
Addq.w #1,d0
Lsr.w #1,d0
Subq.w #1,d0
.Loop Move.l (a0),d1
Lsr.l #8,d1
Addq.l #2,a0
And.l d7,d1
Move.l (a0)+,d2
And.l d7,d2
Add.l d1,d2
Lsr.l #1,d2
IFNE MC68000
Move.b d2,2(a1)
Lsr.w #8,d2
Move.b d2,1(a1)
Swap d2
Move.b d2,(a1)
ELSE
Move.w d2,1(a1)
Swap d2
Move.b d2,(a1)
ENDC
Addq.l #3,a1
Dbra d0,.Loop
Movem.l (sp)+,a0-a1
Rts
;RGBScaler ; IN: a0.l = Ptr to RGB line (3 words/color)
; Movem.l d0-d7/a0-a3,-(sp)
; Move.w PicW(a5),d1
; Move.w ScaleLevel(a5),d0
; Move.w d0,d7
; Move.l a0,a1
;
; Lea ScaleTable(pc),a2
; Move.w VerScale(a5),d2
; Add.w d0,d2
; Cmp.w #16,d2
; Bge.s .ScaleIt
; Move.w d2,VerScale(a5)
; Bra .Exit
;
;.ScaleIt Sub.w #16,d2
; Move.w d2,VerScale(a5)
;
;.Scale Moveq #16,d2
; Sub.w d7,d2
; Move.w (a0)+,d3
; Move.w (a0)+,d4
; Move.w (a0)+,d5
; Move.l (a2,d7.w*4),a3
; Move.w (a3,d3.w*2),d3
; Move.w (a3,d4.w*2),d4
; Move.w (a3,d5.w*2),d5
; Subq.w #1,d1
; Cmp.w d0,d2
; Bge.s .Again
; Bra.s .Lower
;
;.Again Sub.w d0,d2
; Move.l (a2,d0.w*4),a3
;
; Move.w (a0)+,d6
; Add.w (a3,d6.w*2),d3
; Move.w (a0)+,d6
; Add.w (a3,d6.w*2),d4
; Move.w (a0)+,d6
; Add.w (a3,d6.w*2),d5
; Subq.w #1,d1
; Cmp.w d0,d2
; Bge.s .Again
;
;.Lower Tst.w d2
; Beq.s .Skip
; Move.l (a2,d2.w*4),a3
; Move.w (a0),d6
; Add.w (a3,d6.w*2),d3
; Move.w 2(a0),d6
; Add.w (a3,d6.w*2),d4
; Move.w 4(a0),d6
; Add.w (a3,d6.w*2),d5
;
;.Skip Move.w d0,d7
; Sub.w d2,d7
;
; Lsr.w #4,d3
; Lsr.w #4,d4
; Lsr.w #4,d5
;
; Move.w d3,(a1)+
; Move.w d4,(a1)+
; Move.w d5,(a1)+
;
;.Skip3 Tst.w d1
; Bgt .Scale
; Moveq #0,d0
; Bra.s .Exit2
;
;.Exit Moveq #-1,d0
;.Exit2 Movem.l (sp)+,d0-d7/a0-a3
; Rts
CNOP 0,4
RGBScalerSimple ; IN: a0.l = Ptr to RGB line (3 bytes/color)
; IN: d1.w = Width of RGB line
Movem.l d0-d2/a0-a1,-(sp)
Move.w ScaleLevel(a5),d0
Move.l a0,a1
;Add.w d0,VerScale(a5)
;Blt.s .Exit
;Sub.w #64,VerScale(a5)
.ScaleIt Subq.w #1,d1
Moveq #-32,d2
.Scale Add.w d0,d2
Blt.s .SkipThisOne
Sub.w #64,d2
IFNE MC68000
Move.b (a0)+,(a1)+
Move.b (a0)+,(a1)+
Move.b (a0)+,(a1)+
ELSE
Move.w (a0)+,(a1)+
Move.b (a0)+,(a1)+
ENDC
Dbra d1,.Scale
Bra.s .End
.SkipThisOne Addq.l #3,a0
Bra.s .Scale
.End Moveq #0,d0
.Exit Movem.l (sp)+,d0-d2/a0-a1
Rts
CNOP 0,4
GrayScalerSimple ; IN: a0.l = Ptr to Grayline (1 byte/color)
; IN: d1.w = Width of Gray line
Movem.l d0-d2/a0-a1,-(sp)
Move.w ScaleLevel(a5),d0
Move.l a0,a1
;Add.w d0,VerScale(a5)
;Blt.s .Exit
;Sub.w #64,VerScale(a5)
.ScaleIt Subq.w #1,d1
Moveq #-32,d2
.Scale Add.w d0,d2
Blt.s .SkipThisOne
Sub.w #64,d2
Move.b (a0)+,(a1)+
Dbra d1,.Scale
Bra.s .End
.SkipThisOne Addq.l #1,a0
Bra.s .Scale
.End Moveq #0,d0
.Exit Movem.l (sp)+,d0-d2/a0-a1
Rts
CNOP 0,4
PaletteScalerSimple ; IN: a0.l = Ptr to Palette line (1 byte/pixel)
; IN: d1.w = Width of palette line
Movem.l d0-d2/a0-a1,-(sp)
Move.w ScaleLevel(a5),d0
Move.l a0,a1
;Add.w d0,VerScale(a5)
;Blt.s .Exit
;Sub.w #64,VerScale(a5)
.ScaleIt Subq.w #1,d1
Moveq #-32,d2
.Scale Add.w d0,d2
Blt.s .SkipThisOne
Sub.w #64,d2
Move.b (a0)+,(a1)+
Dbra d1,.Scale
Bra.s .End
.SkipThisOne Addq.l #1,a0
Bra.s .Scale
.End Moveq #0,d0
.Exit Movem.l (sp)+,d0-d2/a0-a1
Rts
CNOP 0,4
RGBtoBWdither ; IN: a0.l = Ptr to Gray line (1 byte/color) (unscaled)
; IN: a1.l = Ptr to output buffer
; IN: d0.w = Length of RGB in pixels
; IN: d1.w = Shift final output data d1 bits to right
;COM: d0-d2 destroyed
Movem.l a0-a3,-(sp)
Subq.w #1,d0
Move.l Floyd1(a5),a2
Move.l Floyd2(a5),a3
Move.l a3,Floyd1(a5)
Move.l a2,Floyd2(a5)
Moveq #0,d2
Clr.w (a3)
Moveq #8,d4
Sub.w d1,d4
.Loop Moveq #0,d3
Move.b (a0)+,d3
Add.w (a2)+,d3
Bge.s .OkA
Moveq #0,d3
.OkA Cmp.w #255,d3
Ble.s .OkA1
Move.w #255,d3
.OkA1 Move.w d3,d2
Lsr.w d1,d2
Move.b d2,(a1)+
Move.w d3,d5
Lsr.w d4,d5
Lsl.w d1,d2
Or.w d5,d2
;d3 = Color needed d2 = Color chosen
Sub.w d2,d3
Asr.w #2,d3
Add.w d3,(a2)
Add.w d3,-2(a3)
Add.w d3,(a3)+
Move.w d3,(a3)
Dbra d0,.Loop
Movem.l (sp)+,a0-a3
Rts
CNOP 0,4
RGBtoBW ; IN: a0.l = Ptr to RGB line (1 byte/color) (unscaled)
; IN: a1.l = Ptr to output buffer
; IN: d0.w = Length of RGB in pixels
; IN: d1.w = Shift final output data d1 bits to right
;COM: d0/d2 destroyed
Movem.l a0-a1,-(sp)
Subq.w #1,d0
Moveq #0,d2
.Loop Move.b (a0)+,d2
Lsr.w d1,d2
Move.b d2,(a1)+
Dbra d0,.Loop
Movem.l (sp)+,a0-a1
Rts
; CNOP 0,4
;PlanarToPlanar ; IN: a0.l = Ptr to planar-data
; ; IN: a1.l = Ptr to Screen
; ; IN: a4.l = ScreenNode
; ; IN: d1.w = OutputLine
; ; IN: d2.w = RenderW
;
; Add.w #15,d2
; Lsr.w #4,d2
; Subq.w #1,d2
;
; Move.l 88(a1),a2 a2 = bitmap
; Moveq #0,d3
; Move.b 5(a2),d3
; Subq.w #1,d3
; Mulu (a2),d1 BytesPerRow * OutputLine
; Addq.l #8,a2
;
;.BPLoop Move.l (a2)+,a1
; Add.l d1,a1
; Move.w d2,d0
;.XLoop Move.w (a0)+,(a1)+
; Dbra d0,.XLoop
; Dbra d3,.BPLoop
;
; Rts